//
//  thread_func.cpp
//  testpcap
//
//  Created by bugforever on 1/10/15.
//  Copyright (c) 2015 bugforever. All rights reserved.
//

#include "thread_func.h"

#include "thread_func.h"

#ifdef _WIN32
#include <windows.h>
#elif defined LINUX
#include <sys/mman.h>
#include <pthread.h>
#include <sys/prctl.h>
#else
#include <pthread.h>
#endif

int create_thread( THREAD_HANDLE * ptr_thread_handle, long * ptr_thread_id, ptr_thread_func ptr_func, void * ptr_param, unsigned int flag, unsigned int stack_size )
{
    if (ptr_thread_handle == 0 || ptr_thread_id == 0)
        return -1;
    
    *ptr_thread_handle = 0;
    *ptr_thread_id = 0;
    
    int ret = 0;
    
#ifdef _WIN32
    
	*ptr_thread_handle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ptr_func, ptr_param, 0, (LPDWORD)ptr_thread_id);
    
	if (*ptr_thread_handle == 0)
        return -1;
    
#elif defined LINUX
    
    /*//strong concern of the code
     pthread_t 		tt;
     pthread_attr_t	attr;
     
     pthread_attr_init(&attr);
     pthread_attr_setstacksize(&attr, stack_size);
     
     ret = pthread_create(&tt, &attr, (void*(*)(void*))ptr_func ,ptr_param);
     
     if (rs != 0)
     return -1;
     
     *ptr_thread_handle = (THREAD_HANDLE)tt;
     *ptr_thread_id = (unsigned int)tt;
     */
    
#else
    
    pthread_attr_t  attr;
    pthread_t       tt;
    
    ret = pthread_attr_init(&attr);
    
    if( ret != 0 )
        return -1;
    
    ret = pthread_create(&tt, &attr, (void*(*)(void*))ptr_func, ptr_param);
    
    *ptr_thread_handle	= (THREAD_HANDLE)tt;
    *ptr_thread_id		= (long)tt;
    
#endif
    
    return ret;
}

int exit_thread()
{
    int ret = 0;
#ifdef _WIN32
	;
#elif LINUX
    pthread_exit( &ret );
#else
    pthread_exit( &ret );
#endif
    
    return ret;
}

void wait_thread_exit( THREAD_HANDLE thread_handle )
{
    if( thread_handle == 0 )
        return;
    
#ifdef _WIN32
    WaitForSingleObject( thread_handle , INFINITE );
#elif defined LINUX
    pthread_join( (pthread_t)thread_handle , 0 );
#else
    pthread_join( (pthread_t)thread_handle , 0 );
#endif
}

void set_thread_name( const char * str_name )
{
#ifdef _LINUX_ANDROID
    prctl(PR_SET_NAME, (unsigned long)ptr_name , 0 , 0 , 0);
#endif
}

long get_current_thread_id (void)
{
#ifdef _WIN32
    return (int) GetCurrentThreadId ();
#elif defined _LINUX
    return (int) pthread_self ();
#else
    return (long) pthread_self ();
#endif
}

